JDBC连接池的简单实现 - 貌似掉线的博客 - 博客频道 - CSDN.NET

创建时间:2017/2/10 11:09
来源:http://blog.csdn.net/maosidiaoxian/article/details/36478397


分类:
Java笔记(15) web笔记(2)
.

版权声明:本文为博主原创文章,未经博主允许不得转载。

先说明一下,我本身是做Android开发的,Java web是我的弱项,只是近来京东云免费,于是去折腾了几下,有了些许经验,特作分享。如果文章中内容有误,还请各高手指正。

我在web端,需要连接数据库进行查询插入等操作,但是每次进行操作都先获取连接用完后就断开的话,未免效率太低。以前知道tomcat中可以配置,但是京东云引擎的tomcat并不能由自己配置。因为我折腾的东西较小,所以也不考虑使用框架,于是就想自己写一个。

我写的连接池很简单,在初始化时创建5个连接,并放在一个列表当中。如果要获取连接,从列表中获取,同时列表移除,还回来时,列表添加上。也就是列表保存的是闲置的连接。

如果列表已经为空了,那么判断是否超过最大连接了,没有就创建,有的话就等待。当然,我这里做的是很简单的实现,所以没有去做等待超时等处理。

代码如下:

  1. package com.githang.tucao.web.dbc;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.DriverManager;  
  5. import java.sql.SQLException;  
  6. import java.sql.Statement;  
  7. import java.util.LinkedList;  
  8.   
  9. public class DatabaseConnection {  
  10.     private static final String CREATE_TABLE_TWITTER = "CREATE TABLE IF NOT EXISTS twitter (id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, msg varchar(300) not null) DEFAULT CHARSET=utf8";  
  11.     final static String HOST = "host";  
  12.     final static String PORT = "port";  
  13.     final static String DB_NAME = "dbname";  
  14.     final static String USERNAME = "username";  
  15.     final static String PASSWORD = "password";  
  16.     final static String url = "jdbc:mysql://" + HOST + ":" + PORT + "/" + DB_NAME  
  17.             + "?useUnicode=true&characterEncoding=utf-8";  
  18.     private static final DatabaseConnection instance = new DatabaseConnection();  
  19.     private final int INIT_COUNT = 5;  
  20.     private final int MAX_COUNT = 30;  
  21.     private int count = 0;  
  22.       
  23.     private final Object wait = new Object();  
  24.       
  25.     private  LinkedList<Connection> CONN_POOL;  
  26.   
  27.     private DatabaseConnection() {  
  28.         CONN_POOL = new LinkedList<Connection>();  
  29.         try {  
  30.             Class.forName("com.mysql.jdbc.Driver");  
  31.             for (int i = 0; i < INIT_COUNT; i++) {  
  32.                 Connection connection = createConnection();  
  33.                 if(connection != null) {  
  34.                     CONN_POOL.add(createConnection());  
  35.                     count++;  
  36.                 }  
  37.             }  
  38.      //       Connection connection = getConnection();  
  39.      //       Statement stmt = connection.createStatement();  
  40.      //       stmt.execute(CREATE_TABLE_TWITTER);  
  41.      //       stmt.execute("set names 'utf-8'");  
  42.      //       stmt.close();  
  43.      //       releaseConnection(connection);  
  44.         } catch (Exception e) {  
  45.             e.printStackTrace();  
  46.         }  
  47.     }  
  48.       
  49.     public static DatabaseConnection getInstance() {  
  50.         return instance;  
  51.     }  
  52.       
  53.     private static Connection createConnection() {  
  54.         try {  
  55.             return DriverManager.getConnection(url, USERNAME, PASSWORD);  
  56.         } catch (SQLException e) {  
  57.             e.printStackTrace();  
  58.         }  
  59.         return null;  
  60.     }  
  61.   
  62.     public Connection getConnection() {  
  63.         synchronized (CONN_POOL) {  
  64.             while(CONN_POOL.size() > 0) {  
  65.                 Connection conn = CONN_POOL.removeLast();  
  66.                 try {  
  67.                     if(conn.isValid(1000)) {  
  68.                         return conn;  
  69.                     } else {  
  70.                         count--;  
  71.                     }  
  72.                 } catch (SQLException e) {  
  73.                     e.printStackTrace();  
  74.                 }  
  75.             }  
  76.             if(count < MAX_COUNT) {  
  77.                 count++;  
  78.                 return createConnection();  
  79.             }   
  80.             synchronized (wait) {  
  81.                 try {  
  82.                     wait.wait(3000);  
  83.                     if(CONN_POOL.size() > 0) {  
  84.                         return CONN_POOL.removeLast();  
  85.                     }  
  86.                 } catch (InterruptedException e) {  
  87.                     e.printStackTrace();  
  88.                 }  
  89.             }  
  90.         }  
  91.         return null;  
  92.     }  
  93.   
  94.     public void releaseConnection(Connection connection) {  
  95.         CONN_POOL.add(connection);  
  96.         synchronized (wait) {  
  97.             wait.notify();  
  98.         }  
  99.     }  
  100.       
  101. }  
其中count用于保存当前连接数(包括闲置和在使用的)。

wait对象用于线程同步锁,主要是获取不到连接并且需要等其他连接被还回来时使用,在getConnection()里面调用 wait,而在releaseConnection()方法中,也就是释放连接时,调用 notify通知其他等待的线程。

另外,在公用的数据库当中,数据库连接通常是不作长连接的。所以在这里连接池中的连接,可能是已经断开的或者是无效的,所以在获取连接时需要判断一下当前拿到的连接是否还有效。没有的话就拿下一个。

.
1
1

我的同类文章